package com.zqxq.lottery.api.controller;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.zqxq.common.constant.Result;
import com.zqxq.common.enums.CodeEnum;
import com.zqxq.common.utils.DispatcherUtils;
import com.zqxq.common.utils.StrUtils;
import com.zqxq.common.utils.ValidateUtils;
import com.zqxq.common.utils.WebUtils;
import com.zqxq.lottery.api.feign.LotteryServerFeignClient;
import com.zqxq.lottery.api.service.IAlipayService;
import com.zqxq.lottery.api.utils.MobileUtil;
import com.zqxq.lottery.api.utils.UserCenterHttps;
import com.zqxq.lottery.entity.bo.LoginBO;
import com.zqxq.lottery.entity.vo.user.UserInfoVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;

/**
 * @Description ：
 * @Author ： 解风
 * @Date ： 2018/01/02 14:26
 */
@Api(value = "登录接口",tags = "登录接口")
@RestController
@Slf4j
@RequestMapping(value="/login",produces = "application/json")
public class LoginController {

    @Autowired
    private UserCenterHttps userCenterHttps;

    @Autowired
    private LotteryServerFeignClient lotteryServerFeignClient;

    @Autowired
    private IAlipayService alipayService;
    /**
     * 用户密码登录
     * @param loginBO
     * @return
     */
    @PostMapping("/password")
    @ApiOperation(value = "用户密码登录", notes = "用户密码登录")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "mobile", value = "手机号码", required = true, paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "password", value = "登录密码", required = true, paramType = "query", dataType = "String", defaultValue = "''")
    })
    public Result password(HttpServletRequest request, LoginBO loginBO) {
        log.info("手机用户【" + loginBO.getMobile() + "】正在登录" + ",用户所在" + loginBO.getAppKey() + "平台");
        String regIp = WebUtils.getClientIP(request);
        try {
            String mobile = loginBO.getMobile();
            String password = loginBO.getPassword();
            if (StrUtils.isEmpty(mobile)|| !MobileUtil.isMobile(mobile) || StrUtils.isEmpty(password)) {
                return new Result(CodeEnum.FAIL_100002.getCode(), CodeEnum.FAIL_100002.getMsg());
            }
            Map<String, Object> resultMap = userCenterHttps.loginByPassword(loginBO);
            int code = CodeEnum.FAIL.getCode();
            String msg = CodeEnum.FAIL.getMsg();
            Map<String, Object> map = new HashMap();
            if(resultMap != null){
                int backCode = resultMap.get("code") == null ? 3 : DispatcherUtils.parseInt(resultMap.get("code"));
                msg = resultMap.get("msg") == null ? CodeEnum.FAIL.getMsg() : resultMap.get("msg").toString();
                if(backCode == 1){
                    code = 0;
                    msg = CodeEnum.SUCCESS.getMsg();
                    Map<String, Object> data = (Map<String, Object>) resultMap.get("data");
                    map.put("userId", data.get("user_id"));
                    map.put("tokenId",data.get("token"));
                }
            }
            return new Result(code, msg, map);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("登录失败！", e);
            return new Result(CodeEnum.FAIL_100005.getCode(), CodeEnum.FAIL_100005.getMsg());
        }
    }

    /**
     * 用户验证码登录
     * @param loginBO
     * @return
     */
    @PostMapping("/verifyCode")
    @ApiOperation(value = "用户验证码登录", notes = "用户验证码登录")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "mobile", value = "手机号码", required = true, paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "verifyCode", value = "验证码", required = true, paramType = "query", dataType = "String", defaultValue = "''")
    })
    public Result verifyCode(HttpServletRequest request, LoginBO loginBO) {
        log.info("手机用户【" + loginBO.getMobile() + "】正在登录" + ",用户所在" + loginBO.getAppKey() + "平台");
        String regIp = WebUtils.getClientIP(request);
        try {
            String mobile = loginBO.getMobile();
            String verifyCode = loginBO.getVerifyCode();
            if (StrUtils.isEmpty(mobile) || !MobileUtil.isMobile(mobile) || StrUtils.isEmpty(verifyCode)) {
                return new Result(CodeEnum.FAIL_100002.getCode(), CodeEnum.FAIL_100002.getMsg());
            }
            Map<String, Object> resultMap = userCenterHttps.loginByVerifyCode(loginBO);
            int code = CodeEnum.FAIL.getCode();
            String msg = CodeEnum.FAIL.getMsg();
            Map<String, Object> map = new HashMap<String, Object>();
            if(resultMap != null){
                int backCode = resultMap.get("code") == null ? 3 : DispatcherUtils.parseInt(resultMap.get("code"));
                msg = resultMap.get("msg") == null ? CodeEnum.FAIL.getMsg() : resultMap.get("msg").toString();
                if(backCode == 1){
                    code = 0;
                    msg = CodeEnum.SUCCESS.getMsg();
                    Map<String, Object> data = (Map) resultMap.get("data");
                    map.put("userId", data.get("user_id"));
                    map.put("tokenId",data.get("token"));
                }else{
                    log.error("登录失败！");
                }
            }
            return new Result(code, msg, map);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("登录失败！", e);
            return new Result(CodeEnum.FAIL_100005.getCode(), CodeEnum.FAIL_100005.getMsg());
        }
    }


    /**
     * 用户登录注册
     * @param loginBO
     * @return
     */
    @PostMapping("/loginRegister")
    @ApiOperation(value = "用户登录注册", notes = "用户登录注册")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "mobile", value = "手机号码", required = true, paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "verifyCode", value = "验证码", required = true, paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "isH5", value = "是否为H5页面注册", required = false, paramType = "query", dataType = "String")
    })
    public Result loginRegister(HttpServletRequest request, LoginBO loginBO,boolean isH5) {
        log.info("手机用户【" + loginBO.getMobile() + "】正在登录" + ",用户所在" + loginBO.getAppKey() + "平台");
        String regIp = WebUtils.getClientIP(request);
        try {
            String mobile = loginBO.getMobile();
            if(isH5) {
                //如果是H5注册判断这个手机号是否已经注册，如果已经注册则不能继续注册
                Result rs = lotteryServerFeignClient.getUserInfoByMobile(mobile);
                Integer count = DispatcherUtils.parseInteger(rs.getData());
                if(count>0){
                    return new Result(100006, "该手机号已经注册！");
                }
            }

            String verifyCode = loginBO.getVerifyCode();
            if (StrUtils.isEmpty(mobile)|| !MobileUtil.isMobile(mobile) || StrUtils.isEmpty(verifyCode)) {
                return new Result(CodeEnum.FAIL_100002.getCode(), CodeEnum.FAIL_100002.getMsg());
            }
            Map<String, Object> resultMap = userCenterHttps.loginRegister(loginBO);
            int code = CodeEnum.FAIL.getCode();
            String msg = CodeEnum.FAIL.getMsg();
            Map<String, Object> map = new HashMap<String, Object>();
            if(resultMap != null){
                int backCode = resultMap.get("code") == null ? 3 : DispatcherUtils.parseInt(resultMap.get("code"));
                msg = resultMap.get("msg") == null ? CodeEnum.FAIL.getMsg() : resultMap.get("msg").toString();
                if(backCode == 1){
                    code = 0;
                    msg = CodeEnum.SUCCESS.getMsg();
                    //保存用户信息
                    Map<String, Object> data = (Map) resultMap.get("data");
                    map.put("userId", data.get("user_id"));
                    map.put("tokenId",data.get("token"));
                    UserInfoVO vo = new UserInfoVO();
                    String userId = DispatcherUtils.parseString(data.get("user_id"));
                    vo.setUserId(userId);
                    vo.setChannel(DispatcherUtils.parseString(request.getParameter("channel")));
                    vo.setSource(DispatcherUtils.parseString(request.getParameter("source")));
                    vo.setEquipmentId(DispatcherUtils.parseString(request.getParameter("equipmentId")));
                    vo.setPhoneModel(DispatcherUtils.parseString(request.getParameter("phoneModel")));
                    String city = DispatcherUtils.parseString(request.getParameter("city"));
                    if(!StringUtils.isEmpty(city) && !city.equals(",")){
                        vo.setCity(getAdd(city.split(",")[1],city.split(",")[0]));
                    }
                    vo.setAppKey(loginBO.getAppKey());
                    vo.setMobile(mobile);
                    vo.setActivityId(loginBO.getActivityId());
                    vo.setInviterId(loginBO.getInviterId());
                    Result rs = lotteryServerFeignClient.saveUserInfo(vo);
                    if(!rs.success()){
                        return rs;
                    }
                }
            }
            return new Result(code, msg, map);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("登录失败！", e);
            return new Result(CodeEnum.FAIL_100005.getCode(), CodeEnum.FAIL_100005.getMsg());
        }
    }

    /**
     * 用户第三方登录
     * @param loginBO
     * @return
     */
    @PostMapping("/other")
    @ApiOperation(value = "用户第三方登录", notes = "用户第三方登录 code=300 则走绑定手机号流程")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "mobile", value = "手机号码", required = true, paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "openId", value = "openId", required = true, paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "alipayAccount", value = "支付宝账号ID", required = true, paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "authCode", value = "授权令牌", required = true, paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "type", value = "类型：1- 微信 2-QQ 3--微博、4支付宝", required = true, paramType = "query", dataType = "Integer")
    })
    public Result other(HttpServletRequest request, LoginBO loginBO) {
        log.info("手机用户【" + loginBO.getMobile() + "】正在用户第三方登录" + ",用户所在" + loginBO.getAppKey() + "平台");
        String regIp = WebUtils.getClientIP(request);
        try {
            Integer type =loginBO.getType();
            String tokenId = loginBO.getOpenId();
            if (StrUtils.isEmpty(tokenId) || type == null) {
                return new Result(CodeEnum.FAIL_100002.getCode(), CodeEnum.FAIL_100002.getMsg());
            }
            Map<String, Object> resultMap = userCenterHttps.loginOther(loginBO);
            int code = CodeEnum.FAIL.getCode();
            String msg = CodeEnum.FAIL.getMsg();
            Map<String, Object> map = new HashMap<String, Object>();
            if(resultMap != null){
                int backCode = resultMap.get("code") == null ? 3 : DispatcherUtils.parseInt(resultMap.get("code"));
                msg = resultMap.get("msg") == null ? CodeEnum.FAIL.getMsg() : resultMap.get("msg").toString();
                if(backCode == 1){
                    code = 0;
                    msg = CodeEnum.SUCCESS.getMsg();
                    Map<String, Object> data = (Map) resultMap.get("data");
                    map.put("userId", data.get("user_id"));
                    map.put("tokenId",data.get("token"));
                    map.put("phone", data.get("phone"));

                    String alipayUser = getAlipayUser(loginBO.getAuthCode());
                    log.info("----------->alipayUser:" + alipayUser);
                    String sex = null , city = null;
                    if(StrUtils.isNotEmpty(alipayUser)){
                        JSONObject jsonObject = JSONObject.parseObject(alipayUser);
                        JSONObject json = jsonObject.getJSONObject("alipay_user_info_share_response");
                        if("10000".equals(json.getString("code"))){
                            sex = "M".equalsIgnoreCase(json.getString("gender")) ? "2" : "1";
                            city = json.getString("city");
                        }
                    }

                    UserInfoVO vo = new UserInfoVO();
                    String userId = DispatcherUtils.parseString(data.get("user_id"));
                    vo.setAppKey(loginBO.getAppKey());
                    vo.setUserId(userId);
                    vo.setChannel(DispatcherUtils.parseString(request.getParameter("channel")));
                    vo.setSource(DispatcherUtils.parseString(request.getParameter("source")));
                    vo.setEquipmentId(DispatcherUtils.parseString(request.getParameter("equipmentId")));
                    vo.setPhoneModel(DispatcherUtils.parseString(request.getParameter("phoneModel")));
                    vo.setMobile(DispatcherUtils.parseString(data.get("phone")));
                    vo.setAlipayAccount(loginBO.getAlipayAccount());
                    vo.setSex(sex);
                    vo.setCity(city);
                    Result rs = lotteryServerFeignClient.saveUserInfo(vo);
                    if(!rs.success()){
                        return rs;
                    }
                } else {
                    code = backCode; //code = 300 走签约流程
                }
            }
            return new Result(code, msg, map);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("登录失败！", e);
            return new Result(CodeEnum.FAIL_100005.getCode(), CodeEnum.FAIL_100005.getMsg());
        }
    }



    private String getAlipayUser(String authCode){
        return alipayService.getUser(alipayService.getAccessToken(authCode));
    }
    public static String getAdd(String log, String lat){
        //lat 小  log  大
        //参数解释: 纬度,经度 type 001 (100代表道路，010代表POI，001代表门址，111可以同时显示前三项)
        String urlString = "http://gc.ditu.aliyun.com/regeocoding?l="+lat+","+log+"&type=010";
        String add = "";
        String res = "";
        try {
            URL url = new URL(urlString);
            java.net.HttpURLConnection conn = (java.net.HttpURLConnection)url.openConnection();
            conn.setDoOutput(true);
            conn.setRequestMethod("POST");
            java.io.BufferedReader in = new java.io.BufferedReader(new java.io.InputStreamReader(conn.getInputStream(),"UTF-8"));
            String line;
            while ((line = in.readLine()) != null) {
                res += line+"\n";
            }
            in.close();
        } catch (Exception e) {
            System.out.println("error in wapaction,and e is " + e.getMessage());
        }
        if(StringUtils.isEmpty(res)){
            return null;
        }
        JSONObject jsonObject = JSONObject.parseObject(res);
        JSONArray jsonArray = jsonObject.getJSONArray("addrList");
        JSONObject j_2 = JSONObject.parseObject(String.valueOf(jsonArray.get(0)));
        String allAdd = j_2.getString("admName");
        String arr[] = allAdd.split(",");
        if(arr!=null && arr.length!=0){
            add = arr[1];
        }
        return add;
    }
}
